﻿using System;
using System.Collections.Generic;
using System.IO;
using gsToolkit;
using System.Linq;

namespace gSharp {
    public class gSharpConsole {

//-------|---------|---------|---------|---------|---------|---------|---------|
        private static gSharpConsole gsc;
        private static bool failTripped;

        private static string help = @"
Usage:
-------
g# [options] <scriptFile> [scriptOptions]

    options:
    --------
    --help                      this help
    --nologo                    don't display the logo
    --load-config=<configfile>  loads options from configuration file
                                List the options, one per line, without the
                                prefix '--'.

    --debug                     include debug info and hints with script
    --exe=<exeName>             create console EXE from script 
    --gui-exe=<exeName>         create gui EXE from script 

    --compile                   just compile/process the script, not execute
    --clear-cache               clears all the cached scripts

";

        [STAThread]
        static int Main(string[] args) {
            gsc = new gSharpConsole();
            int result = gsc.main(args);
            return result;
        }

        private gsToolkit.gSharp.ScriptProcessor Processor {
            get {
                return gsToolkit.gSharp.ScriptProcessor.Instance;
            }
        }

        int main(string[] args) {
            #region Options and Parameters

            foreach (var arg in args.Switches().Keys) {
                List<string> parameters = args.Switches()[arg];

                switch (arg) {
                    case "load-config":
                        // all ready done, but don't get too picky.
                        break;

                    case "nologo":
                        this.Assembly().SetLogo("");
                        break;

                    case "help":
                        Logo();
                        return Help();

                    case "debug":
                        Processor.Debug = true;
                        break;

                    case "compile":
                        Processor.CompileOnly = true;
                        Processor.GenerateOutput = gsToolkit.gSharp.GenerateOptions.Source;
                        break;

                    case "exe":
                        Processor.CompileOnly = true; // implied
                        Processor.GenerateOutput = gsToolkit.gSharp.GenerateOptions.Exe;
                        Processor.OutputFile = Path.GetFullPath(parameters.Last()).ToLower();
                        break;

                    case "dll":
                        Processor.CompileOnly = true; // implied
                        Processor.GenerateOutput = gsToolkit.gSharp.GenerateOptions.Dll;
                        Processor.OutputFile = Path.GetFullPath(parameters.Last()).ToLower();
                        break;

                    case "gui-exe" :
                        Processor.CompileOnly = true; // implied
                        Processor.GenerateOutput = gsToolkit.gSharp.GenerateOptions.GuiExe;
                        Processor.OutputFile = Path.GetFullPath(parameters.Last()).ToLower();
                        break;

                    case "clear-cache" :
                        Logo();
                        Processor.ClearCache(); // act now, we know this is all we're gonna do
                        return 0;

                    default:
                        Logo();
                        return Fail("Unknown option [{0}]", arg);
                }
            }


            #endregion

            Logo();

            if(args.Parameters().Count == 0) {
                Help();
                return 1;
            }
            try {
                Processor.ScriptFilename = Path.GetFullPath(args.Parameters()[0]).ToLower();    
            }
            catch( Exception e ) {
                Fail(e.Message);
            }
            
            args.Parameters().RemoveAt(0);
            return Processor.Process(args.Parameters());
        }

        #region fail/help/logo
        public int Fail(string text, params object[] par) {
            failTripped = true;
            using(new ConsoleColors(ConsoleColor.Red, ConsoleColor.Black))
                Console.WriteLine("Error:{0}", text.format(par));
            return 1;
        }

        int Help() {
            using(new ConsoleColors(ConsoleColor.White, ConsoleColor.Black))
                help.Print();
            return 0;
        }

        void Logo() {
            using(new ConsoleColors(ConsoleColor.Cyan, ConsoleColor.Black))
                this.Assembly().Logo().Print();
            this.Assembly().SetLogo("");
        }
        #endregion
    }
}
